﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using YLPublicService.Extensions;
using System.Data.Common;
using System.Data;

using YLPublicService.TransferModel;

namespace YLPublicService
{
    public static class DataContextExtensions
    {
        public static List<T> ExecuteQuery<T>(this DataContext dataContext, IQueryable query)
        {
            DbCommand command = dataContext.GetCommand(query);
            dataContext.OpenConnection();

            using (DbDataReader reader = command.ExecuteReader())
            {
                return dataContext.Translate<T>(reader).ToList();
            }
        }

        private static void OpenConnection(this DataContext dataContext)
        {
            if (dataContext.Connection.State == ConnectionState.Closed)
            {
                dataContext.Connection.Open();
            }
        }
    }


    public class AdminService : ServiceBase<ServerUser>, IAdminService
    {

        public bool AddAdminUser(string loginName, string pwd, string memo, bool isAdmin, Guid guid)
        {
            if (!isOnline(guid))
                return false;
            //管理员的管理员帐户才能添加管理员
            if (getCurrentUser(guid).IsAdmin == false)
                return false;
            ServerUser admin = new ServerUser
            {
                LoginName = loginName,
                Enabled = true,
                PassWord = new Binary(HashAlgorithm.getHex(pwd)),
                Memo = memo,
                IsAdmin = isAdmin
            };

            try
            {
                ServerUser t;
                if (!TryFindUser(loginName, pwd, out t))
                {
                    dbContext.ServerUsers.InsertOnSubmit(admin);
                    dbContext.SubmitChanges();
                    return true;
                }
                return false;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 设置用户标识，以及创建文件夹。
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="guid"></param>
        /// <returns></returns>
        public bool EnableUser(string loginName, Guid guid)
        {
            if (!isOnline(guid))
                return false;
            var user = dbContext.Users.Where(u => u.LoginName == loginName).First();
            if (user != null)
            {
                user.Enabled = true;
                dbContext.SubmitChanges(ConflictMode.ContinueOnConflict);
                //添加用户帐目记录
                UserAccount account = new UserAccount { UserID = user.UserID, Money = 0m };
                dbContext.UserAccounts.InsertOnSubmit(account);
                dbContext.SubmitChanges();
                //!++ 创建用户文件夹
                settingManager.CreateUserOnDisk(loginName);
                return true;
            }
            return false;
        }
        /// <summary>
        /// 设置用户标识，但不会删除用户文件夹
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="guid"></param>
        /// <returns></returns>
        public bool DisableUser(string loginName, Guid guid)
        {
            if (isOnline(guid))
            {
                var user = dbContext.Users.Where(u => u.LoginName == loginName).First();
                if (user != null)
                {
                    user.Enabled = false;
                    dbContext.SubmitChanges();
                    return true;
                }
            }
            return false;
        }

        public IEnumerable<TransferModel.User> GetUsers(Guid guid)
        {
            if (isOnline(guid))
            {
                ServerUser serverUser = getCurrentUser(guid);

                var r = from relation in dbContext.ServerUserAndUsers
                        where relation.ServerUserID == serverUser.ServerUserID
                        select relation;
                var ret = from user in dbContext.Users
                          join relation in r on user.UserID equals relation.UserID
                          select TransferModel.User.Create(user.LoginName, user.Enabled);
                return ret;
            }
            else
                return null;
        }
        /// <summary>
        ///  //!+ 集合添加时是否需要事务控制
        /// </summary>
        /// <param name="serverUserLoginName"></param>
        /// <param name="guid"></param>
        /// <returns></returns>
        public bool ConbindAll(string serverUserLoginName, Guid guid)
        {
            var serverid = (from su in dbContext.ServerUsers
                            where su.LoginName == serverUserLoginName
                            select su.ServerUserID).First();

            var newItem = dbContext.Users.ToList().Select(
                u => new ServerUserAndUser { ServerUserID = serverid, UserID = u.UserID }
                );
            var oldItem = from r in dbContext.ServerUserAndUsers
                          where r.ServerUserID == serverid
                          select r;
            try
            {
                dbContext.ServerUserAndUsers.DeleteAllOnSubmit(oldItem);
                dbContext.ServerUserAndUsers.InsertAllOnSubmit(newItem);
                dbContext.SubmitChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool AddUser(string loginName, string pwd, string userName, string memo, Guid guid)
        {
            if (isOnline(guid))
            {
                User user = new User() { UserName = userName, Enabled = false, memo = memo, LoginName = loginName };
                user.PassWord = new Binary(HashAlgorithm.getHex(pwd));
                try
                {
                    //不得重复添加
                    if (dbContext.Users.Where(u => u.LoginName == loginName).Count() != 0)
                        return false;
                    dbContext.Users.InsertOnSubmit(user);
                    dbContext.SubmitChanges();
                    //!+ 添加ftp上的帐户
                    settingManager.AddUser(loginName, pwd);
                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
            }
            return false;
        }
        /// <summary>
        /// 删除用户帐户，以及文件夹
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="guid"></param>
        /// <returns></returns>
        public bool DeleteUser(string loginName, Guid guid)
        {
            if (isOnline(guid))
            {
                try
                {
                    var user = dbContext.Users
                       .Where(u => u.LoginName == loginName).First();
                    dbContext.Users.DeleteOnSubmit(user);
                    dbContext.SubmitChanges();
                    //!+ delete ftp user 
                    settingManager.DeleteUser(loginName);
                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
            }
            return false;
        }
        /// <summary>
        /// 获取用户所有工作项
        /// </summary>
        /// <param name="userLoginName"></param>
        /// <param name="guid"></param>
        /// <returns></returns>
        public IEnumerable<TransferModel.WorkItem> GetWorkItems(string userLoginName, Guid guid)
        {
            if (isOnline(guid))
            {
                var users = dbContext.Users.Where(u => u.LoginName == userLoginName);
                if (users.Count() < 1)
                {
                    return null;
                }
                var user = users.First();
                var ret =
                    dbContext.View_UserAndItems
                    .Where(item =>
                           item.UserID == user.UserID)
                    .Select(item =>
                           new TransferModel.WorkItem
                           {
                               boyName = item.boyName,
                               grilName = item.grilName,
                               TemplateName = item.TemplateName,
                               Time = item.Time,
                               Status = item.discription,
                               DBTime = item.DBTime
                           });
                return ret;
            }
            return null;
        }
        /// <summary>
        /// 获取等待制作的工作项
        /// </summary>
        /// <param name="userLoginName"></param>
        /// <param name="guid"></param>
        /// <returns></returns>
        public IEnumerable<TransferModel.WorkItem> GetWaitingProcessWorkItems(string userLoginName, Guid guid)
        {
            if (isOnline(guid))
            {
                var users = dbContext.Users.Where(u => u.LoginName == userLoginName);
                if (users.Count() < 1)
                {
                    return null;
                }
                var user = users.First();
                var ret =
                    dbContext.View_UserAndItems
                    .Where(item =>
                           item.UserID == user.UserID &&
                           item.Status == TransferModel.WorkItemStatus.WaitingProcess.GetID())
                    .Select(item =>
                           new TransferModel.WorkItem
                          {
                              boyName = item.boyName,
                              grilName = item.grilName,
                              TemplateName = item.TemplateName,
                              Time = item.Time,
                              Status = item.discription,
                              DBTime = item.DBTime
                          });
                return ret.ToList();
            }
            return null;
        }

        /// <summary>
        /// 尝试匹配一个ServerUser
        /// 信息不对以及没有启用都返回False
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="pwd"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        protected override bool TryFindUser(string loginName, string pwd, out ServerUser user)
        {
            var ret = from u in dbContext.ServerUsers
                      where u.LoginName == loginName && u.PassWord == new Binary(HashAlgorithm.getHex(pwd))
                      select u;

            if (ret.Count() > 0)
            {
                user = ret.First();
                return true;
            }
            else
            {
                user = null;
                return false;
            }
        }

        /// <summary>
        /// 最高管理员才可以更新,money可正负
        /// </summary>
        /// <param name="userLoginName"></param>
        /// <param name="money">可正负</param>
        /// <param name="guid"></param>
        public void UpdateUserAccount(string userLoginName, decimal money, Guid guid)
        {
            if (!isOnline(guid))
                return;
            if (getCurrentUser(guid).IsAdmin == false)
                return;
            var accout = from u in dbContext.Users
                         join account in dbContext.UserAccounts on u.UserID equals account.UserID
                         where u.LoginName == userLoginName
                         select account;
            accout.First().Money += money;
            dbContext.SubmitChanges();
        }


        public void DeleteWorkItems(string userLoginName, Guid guid)
        {
            if (!isOnline(guid))
                return;
            var items = from u in dbContext.Users
                        where u.LoginName == userLoginName
                        join ui in dbContext.UsersItems on u.UserID equals ui.UserID
                        join item in dbContext.WorkItems on ui.ItemID equals item.ItemID
                        select item;

            foreach (var item in items)
            {
                settingManager.DeleteWorkItemDir(userLoginName, item.boyName, item.grilName);
            }

            dbContext.WorkItems.DeleteAllOnSubmit(items);
            dbContext.SubmitChanges();
        }

        public void DeleteWorkItem(string userLoginName, string boyName, string grilName, Guid guid)
        {
            if (!isOnline(guid))
                return;
            var item = (from i in dbContext.WorkItems
                        where i.boyName == boyName && i.grilName == grilName
                        select i).First();
            settingManager.DeleteWorkItemDir(userLoginName, boyName, grilName);
            dbContext.WorkItems.DeleteOnSubmit(item);
            dbContext.SubmitChanges();
        }


        public void UpdateWorkItem(string userLoginName, string boyName, string grilName, WorkItemStatus status, Guid guid)
        {
            throw new NotImplementedException();
        }
    }
}
